home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / Apps / Utilities / Hardware / SCSItools / sense1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-26  |  6.7 KB  |  265 lines

  1. /*
  2.  * sense - dumps SCSI sense page codes
  3.  *      by Charles E. Chambers (chambers@uh.edu)
  4.  *      Mar 20, 1991
  5.  */
  6.  
  7. /*
  8.                       USE AT YOUR OUR RISK. 
  9.       I NOT NOT BE RESPONSIBLE FOR PROBLEM CAUSED BY THIS PROGRAM.
  10.  
  11. Note that I have only tested these programs on a small number of drives (see PARAMETERS directories). BE CAREFUL, if you do not know what you are doing, then I recommend that you not use it. But it is very useful for those people that do know.
  12.  */
  13.  
  14. #include <fcntl.h>
  15. #include <stdio.h>
  16. #include <sys/types.h>
  17. #include <nextdev/scsireg.h>
  18.  
  19. static char *dev_name="/dev/sg0";    /* generic scsi interface */
  20.  
  21. int scsi_open(int target, int lun);
  22. void scsi_show_mode_sense_format(int fd, int lun, int pagecode);
  23. void scsi_show_inquiry(int fd, int lun);
  24. int gs_inquiry(int fd, int lun, int clen, u_char *data);
  25. int gs_mode_sense(int fd, int lun, int ccode, int cfield, int clen, u_char *data);
  26. int gs_mode_select(int fd, int lun, int clen, u_char *data);
  27. int gs_request_sense(int fd, int lun);
  28.  
  29. main(int argc, char *argv[])
  30. {
  31.     extern int optind;
  32.     extern char *optarg;
  33.  
  34.     char c;
  35.  
  36.     int fd;
  37.     int target = -1;
  38.     int lun = -1;
  39.     int pagecode = -1;
  40.  
  41.     while ((c = getopt(argc, argv, "t:l:p:")) != EOF) {
  42.         switch (c) {
  43.         case 't':
  44.             target = atoi(optarg);
  45.             break;
  46.         case 'l':
  47.             lun = atoi(optarg);
  48.             break;
  49.         case 'p':
  50.             pagecode = atoi(optarg);
  51.             break;
  52.         default:
  53.             fprintf(stderr,
  54.                "usage: %s -t<target> [-l<lun>] -p<pagecode>\n",
  55.                 argv[0]);
  56.             exit(1);
  57.         
  58.         }
  59.     }
  60.     if (target == -1) {
  61.         fprintf(stderr,
  62.             "usage: %s -t<target> [-l<lun>] -p<pagecode>\n",
  63.             argv[0]);
  64.         exit(1);
  65.     }
  66.     if (lun == -1) {
  67.         lun = 0;
  68.     }
  69.     if (pagecode == -1) {
  70.         fprintf(stderr,
  71.             "usage: %s -t<target> [-l<lun>] -p<pagecode>\n",
  72.             argv[0]);
  73.         exit(1);
  74.     }
  75.     if ((fd = scsi_open(target, lun)) < 0) {
  76.         fputs("error opening scsi device\n", stderr);
  77.         exit(1);
  78.     }
  79.     scsi_show_inquiry(fd, lun);
  80.     scsi_show_mode_sense_format(fd, lun, pagecode);
  81.     exit(0);
  82. }
  83.  
  84. int scsi_open(int target, int lun)
  85. {
  86.     struct scsi_adr sa;
  87.     int fd;
  88.  
  89.     if ((fd = open(dev_name, O_RDWR)) < 0) {
  90.         fprintf(stderr,"\nCould not open %s\n",dev_name);
  91.         return(-1);
  92.     }
  93.  
  94.     sa.sa_target = target;
  95.     sa.sa_lun = lun;
  96.     if (ioctl(fd,SGIOCSTL,&sa) < 0) {
  97.         fprintf(stderr,"Error setting target %d lun %d\n",target,lun);
  98.         close(fd);
  99.         return(-1);
  100.     }
  101.  
  102.     if(gs_request_sense(fd, lun)) {        /* clear unit attention */
  103.         close(fd);
  104.         return(-1);
  105.     }
  106.     return(fd);
  107. }
  108.  
  109. void scsi_show_inquiry(int fd, int lun)
  110. {
  111.     u_char data[64];
  112.     int i;
  113.     
  114.     bzero(data, sizeof(data));
  115.     if(gs_inquiry(fd, lun, sizeof(data), data)) {
  116.         fputs("error in inquiry\n", stderr);
  117.         close(fd);
  118.         exit(1);
  119.     }
  120.     fprintf(stdout,"#-INQUIRY data\n"); 
  121.     fprintf(stdout,"# vid   /"); 
  122.     for (i=8;i<16;i++) fprintf(stdout,"%c",data[i]);
  123.     fprintf(stdout,"/\n");
  124.     fprintf(stdout,"# pid   /"); 
  125.     for (i=16;i<32;i++) fprintf(stdout,"%c",data[i]);
  126.     fprintf(stdout,"/\n");
  127.     fprintf(stdout,"# firm  /"); 
  128.     for (i=32;i<36;i++) fprintf(stdout,"%c",data[i]);
  129.     fprintf(stdout,"/\n");
  130.     fprintf(stdout, "-ilen %4.4d\n",sizeof(data));
  131.     for (i = 0; i < sizeof(data); i++)
  132.         fprintf(stdout, "-idat %4.4d %2.2x\n"
  133.                      ,i,data[i]);
  134. }
  135.  
  136. void scsi_show_mode_sense_format(int fd, int lun, int pagecode)
  137. {
  138.     u_char current[128];
  139.     u_char mask[128];
  140.     u_char deflt[128];
  141.     u_char saved[128];
  142.     int i,j;
  143.  
  144.     bzero(current, sizeof(current));
  145.     if(gs_mode_sense(fd, lun, pagecode, 0, sizeof(current), current)) {
  146.         fputs("error in mode sense current\n", stderr);
  147.         close(fd);
  148.         exit(1);
  149.     }
  150.     bzero(mask, sizeof(mask));
  151.     if(gs_mode_sense(fd, lun, pagecode, 1, sizeof(mask), mask)) {
  152.         fputs("error in mode sense mask\n", stderr);
  153.         close(fd);
  154.         exit(1);
  155.     }
  156.     bzero(deflt, sizeof(deflt));
  157.     if(gs_mode_sense(fd, lun, pagecode, 2, sizeof(deflt), deflt)) {
  158.         fputs("error in mode sense default\n", stderr);
  159.         close(fd);
  160.         exit(1);
  161.     }
  162.     bzero(saved, sizeof(saved));
  163.     if(gs_mode_sense(fd, lun, pagecode, 2, sizeof(saved), saved)) {
  164.         fputs("error in mode sense saved\n", stderr);
  165.         close(fd);
  166.         exit(1);
  167.     }
  168.     fprintf(stdout,"#-MODE SENSE data\n");
  169.     fprintf(stdout,"-mlen %4.4d\n",saved[0]+1);
  170.     fprintf(stdout,"# Parameter List Header\n");
  171.     fprintf(stdout, "#mhdr offs val msk # cur msk def sav\n");
  172.     for ( i = 0; i <= 3; i++)
  173.         fprintf(stdout, "-mhdr %4.4d  %2.2x  %2.2x #  %2.2x  %2.2x  %2.2x  %2.2x\n"
  174.                      ,i,saved[i]&mask[i],mask[i]
  175.                  ,current[i],mask[i],deflt[i],saved[i]);
  176.     fprintf(stdout,"# Parameter List Block Descriptor Format\n");
  177.     fprintf(stdout, "#mbdf offs val msk # cur msk def sav\n");
  178.     for ( i = 4; i <= saved[3]+3; i++)
  179.         fprintf(stdout, "-mbdf %4.4d  %2.2x  %2.2x #  %2.2x  %2.2x  %2.2x  %2.2x\n"
  180.                      ,i-4,saved[i]&mask[i],mask[i]
  181.                  ,current[i],mask[i],deflt[i],saved[i]);
  182.     for ( i = saved[3]+4; i <= saved[0]; i = i + saved[i+1] + 2) {
  183.         fprintf(stdout, "# Page Code %2.2x\n",saved[i]&63);
  184.         fprintf(stdout, "#mp%2.2d offs val msk # cur msk def sav\n"
  185.             ,saved[i]&63);
  186.         for ( j = 0; j <= saved[i+1]+1; j++)
  187.             fprintf(stdout, "-mp%2.2d %4.4d  %2.2x  %2.2x #  %2.2x  %2.2x  %2.2x  %2.2x\n"
  188.                      ,(saved[i]&63),j,saved[i+j]&mask[i+j],mask[i+j]
  189.                  ,current[i+j],mask[i+j],deflt[i+j],saved[i+j]);
  190.     }
  191.     close(fd);
  192. }
  193.  
  194. int gs_inquiry(int fd, int lun, int clen, u_char *data)
  195. {
  196.     struct scsi_req sr;
  197.     struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
  198.  
  199.     bzero((char *)&sr, sizeof(sr));
  200.     cdbp->c6_opcode = C6OP_INQUIRY;
  201.     cdbp->c6_lun    = lun;
  202.     cdbp->c6_lba    = 0;
  203.     cdbp->c6_len    = clen;
  204.     sr.sr_dma_dir    = SR_DMA_RD;
  205.     sr.sr_addr    = (caddr_t)data;
  206.     sr.sr_dma_max    = clen;
  207.     sr.sr_ioto    = 10;
  208.     return(do_ioc(fd, &sr));
  209. }
  210.  
  211.  
  212. int gs_mode_sense(int fd, int lun, int ccode, int cfield, int clen, u_char *data)
  213. {
  214.     struct scsi_req sr;
  215.     struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
  216.  
  217.     bzero((char *)&sr, sizeof(sr));
  218.     cdbp->c6_opcode = C6OP_MODESENSE;
  219.     cdbp->c6_lun    = lun;
  220.     cdbp->c6_lba    = ((cfield << 14) & 0xc000) | ((ccode << 8) & 0x3f00);
  221.     cdbp->c6_len    = clen;
  222.     sr.sr_dma_dir    = SR_DMA_RD;
  223.     sr.sr_addr    = (caddr_t)data;
  224.     sr.sr_dma_max    = clen;
  225.     sr.sr_ioto    = 10;
  226.     return(do_ioc(fd, &sr));
  227. }
  228.  
  229. int do_ioc(int fd, struct scsi_req *sr)
  230. {
  231.     if (ioctl(fd, SGIOCREQ, sr) < 0) {
  232.         perror("ioctl(SGIOCREQ)");
  233.         return(-1);
  234.     }
  235.     if(sr->sr_io_status) {
  236.         fprintf(stderr,"sr_io_status = 0x%02X\n",sr->sr_io_status);
  237.         if(sr->sr_io_status == SR_IOST_CHKSV) {
  238.             fprintf(stderr,
  239.                 "sense key = 0x%02X, sense code = 0x%02X\n",
  240.                 sr->sr_esense.er_sensekey,
  241.                 sr->sr_esense.er_addsensecode);
  242.         }
  243.         fprintf(stderr,"SCSI status = 0x%02X\n", sr->sr_scsi_status);
  244.         return(-1);
  245.     }
  246.     return(0);
  247. }
  248.  
  249. int gs_request_sense(int fd, int lun)
  250. {
  251.     struct scsi_req sr;
  252.     struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
  253.     u_char sbuf[128];
  254.  
  255.     bzero((char *)&sr, sizeof(sr));
  256.     cdbp->c6_opcode = C6OP_REQSENSE;
  257.     cdbp->c6_lun    = lun;
  258.     cdbp->c6_len    = 18;
  259.     sr.sr_dma_dir    = SR_DMA_RD;
  260.     sr.sr_addr    = (caddr_t)sbuf;
  261.     sr.sr_dma_max    = 128;
  262.     sr.sr_ioto    = 10;
  263.     return(do_ioc(fd, &sr));
  264. }
  265.